ast 모듈
ast 모듈
Python의 ast 모듈은 추상 구문 트리(Abstract Syntax Tree, AST)를 다루기 위한 표준 라이브러리입니다. 이 모듈을 사용하면 Python 코드를 파싱하여 그 구조를 트리 형태로 분석하고, 조작하거나 변환할 수 있습니다. ast 모듈은 정적 분석 도구, 코드 포맷터, 린터, 코드 생성기 등 다양한 프로그래밍 도구의 핵심 기술로 활용됩니다.
개요
ast 모듈은 Python 소스 코드를 구문적으로 분석하고, 이를 Python 객체로 표현하는 기능을 제공합니다. 이 모듈은 내장 함수 compile()이나 eval()과 달리 코드를 실행하지 않고 구문 구조만을 분석하므로, 안전하게 코드를 검사하거나 변형할 수 있습니다.
예를 들어, 다음과 같은 코드가 있을 때:
x = 1 + 2
ast 모듈은 이를 다음과 같은 트리 구조로 변환합니다:
[Module](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/Module)(body=[[Assign](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/Assign)(...)])Assign(targets=[[Name](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/Name)(id='x', ...)], value=[BinOp](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/BinOp)(left=Num(n=1), op=Add(), right=Num(n=2)))
이 구조를 통해 변수 할당, 연산자, 식별자 등을 객체 형태로 접근하고 분석할 수 있습니다.
주요 기능과 사용법
1. 코드 파싱: [ast.parse](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%ED%8C%8C%EC%8B%B1/ast.parse)()
가장 기본적인 기능은 ast.parse() 함수를 사용해 Python 코드를 AST로 변환하는 것입니다.
import ast
code = "x = 1 + 2"
tree = ast.parse(code, mode='exec')
print(ast.dump(tree, indent=2))
출력 예시:
Module(
body=[
Assign(
targets=[
Name(id='x', ctx=Store())
],
value=BinOp(
left=Constant(value=1),
op=Add(),
right=Constant(value=2)
)
)
],
type_ignores=[]
)
mode='exec': 문장(statement) 블록을 파싱 (기본값)mode='eval': 단일 식(expression)을 파싱mode='single': 대화형 모드처럼 단일 문장을 파싱
2. AST 탐색: [ast.NodeVisitor](/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4%EA%B0%9C%EB%B0%9C/%EC%A0%95%EC%A0%81%EB%B6%84%EC%84%9D/ast.NodeVisitor)
ast.NodeVisitor 클래스를 상속하여 AST 내 특정 노드를 탐색할 수 있습니다.
class VariableVisitor(ast.NodeVisitor):
def visit_Name(self, node):
if isinstance(node.ctx, ast.Store):
print(f"변수 할당: {node.id}")
self.generic_visit(node)
tree = ast.parse("x = 1; y = x + 2")
visitor = VariableVisitor()
visitor.visit(tree)
출력:
변수 할당: x
변수 할당: y
3. AST 수정: [ast.NodeTransformer](/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4%EA%B0%9C%EB%B0%9C/%EC%BD%94%EB%93%9C%EB%B3%80%ED%99%98/ast.NodeTransformer)
ast.NodeTransformer를 사용하면 AST를 수정하고 변형된 코드를 다시 생성할 수 있습니다.
예: 모든 숫자를 10배로 만드는 트랜스포머
class MultiplyNumbers(ast.NodeTransformer):
def visit_Constant(self, node):
if isinstance(node.value, int):
return ast.Constant(value=node.value * 10)
return node
tree = ast.parse("x = 5")
tree = MultiplyNumbers().visit(tree)
ast.fix_missing_locations(tree)
# 변환된 코드를 다시 실행
exec(compile(tree, filename="<ast>", mode="exec"))
print(x) # 출력: 50
ast.fix_missing_locations(): 새로운 노드에 위치 정보를 추가하여 컴파일 가능하게 만듭니다.
4. AST 출력: [ast.dump](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EB%94%94%EB%B2%84%EA%B9%85/ast.dump)()와 [ast.unparse](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/%EC%BD%94%EB%93%9C%EC%83%9D%EC%84%B1/ast.unparse)()
ast.dump(tree): AST를 사람이 읽을 수 있는 문자열로 출력 (디버깅용)ast.unparse(tree)(Python 3.9+): AST를 다시 Python 코드 문자열로 변환
tree = ast.parse("x = 1 + 2")
print(ast.unparse(tree)) # 출력: x = 1 + 2
주요 노드 유형
AST는 다양한 노드 클래스로 구성됩니다. 대표적인 것들:
| 노드 클래스 | 설명 |
|---|---|
Module |
전체 코드의 최상위 노드 |
Expr |
표현식 (예: 1 + 2) |
Assign |
변수 할당 (예: x = 1) |
BinOp |
이항 연산 (예: +, -) |
Name |
변수 이름 |
[Constant](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/Constant) |
상수 값 (문자열, 숫자 등) |
[If](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/If), [For](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/For), [While](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/While) |
제어문 |
[FunctionDef](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/FunctionDef) |
함수 정의 |
[Call](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/AST%EB%85%B8%EB%93%9C/Call) |
함수 호출 |
활용 사례
정적 분석 도구
- Pylint, Flake8 등은
ast를 사용해 코드 스타일, 버그, 보안 문제를 탐지합니다.
코드 변환
- 데코레이터나 매크로 같은 기능을 구현할 수 있습니다.
- 예: 특정 함수 호출을 로깅으로 자동 치환.
DSL (도메인 특화 언어)
- Python 문법을 확장하거나 제한하여 사용자 정의 언어를 만들 수 있습니다.
주의사항
ast.parse()는 구문 오류가 있으면SyntaxError를 발생시킵니다.- AST는 Python 버전에 따라 구조가 달라질 수 있으므로, 버전 호환성에 주의해야 합니다.
- AST를 직접 조작할 때는 위치 정보(
lineno,col_offset)를 수동으로 설정해야 할 수 있습니다.ast.fix_missing_locations()를 활용하세요.
관련 문서 및 참고 자료
- 공식 Python 문서: ast 모듈
- Green Tree Snakes - 놀라운 AST 안내서
[lib2to3](/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4%EA%B0%9C%EB%B0%9C/%EC%BD%94%EB%93%9C%EB%B3%80%ED%99%98/lib2to3)라이브러리: Python 2 → 3 변환에ast기반 파서 사용
ast 모듈은 Python의 동적 특성과 함께, 언어 자체를 도구로 삼는 강력한 가능성을 열어주는 핵심 기술입니다.
이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.
주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.